package com.xinghanlaser.applet.base.oss.service;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.PartETag;
import com.amazonaws.services.s3.model.S3Object;
import com.xinghanlaser.applet.base.oss.model.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Set;

/**
 * @description OSS核心调用接口
 * @author 阿爷
 * @createDate  2023/8/28
 */
public interface OssService extends InitializingBean {

    //========================= 【桶 相关操作】 =========================

    /**
     * 桶是否存在
     * @param bucketName 桶名
     * @return true代表存在,false代表不存在
     */
    boolean existBucket(String bucketName);

    /**
     * 创建桶
     * @param bucketName 桶名
     */
    void createBucket(String bucketName);

    /**
     * 获取所有桶对象信息
     * @return 桶Set
     */
    Set<Bucket> getAllBucket();

    /**
     * 根据桶名获取对应桶对象信息
     * @param bucketName 桶名
     * @return 桶对象信息
     */
    Bucket getBucket(String bucketName);

    /**
     * 根据桶名删除对应的桶
     * @param bucketName 桶名
     */
    void removeBucket(String bucketName);

    //========================= 【对象 相关操作】 =========================

    //========= 【查询】 =========
    /**
     * 指定桶下的对象文件是否存在
     * @param objectName 完整对象名
     * @param bucketName 桶名
     * @return
     */
    boolean existObject(String objectName, String bucketName);

    /**
     * 默认桶下的对象文件是否存在
     * @param objectName 完整对象名
     * @return
     */
    boolean existObject(String objectName);

    /**
     * 获取默认桶下的对象Url
     * @param objectName 完整对象名
     * @return Url
     */
    String getPresignedObjectUrl(String objectName);

    /**
     * 获取指定桶下的对象Url
     * @param objectName 完整对象名
     * @param bucketName 桶名
     * @return Url
     */
    String getPresignedObjectUrl(String objectName,String bucketName);

    List<ObjectInfo> getObjectsByPrefix(String bucketName, String prefix);

    List<ObjectInfo> getObjectsByPrefixOfDefaultBucket(String prefix);

    List<ObjectInfo> getAllObjectOfBucket(String bucketName);

    List<ObjectInfo> getAllObjectOfDefaultBucket();
    //========= 【上传】 =========

    /**
     * 上传对象到默认桶
     * @param object 对象文件
     * @return
     */
    UploadObjectResult putObject(MultipartFile object);

    /**
     * 上传对象到指定桶
     * @param object 对象文件
     * @param bucketName 桶名
     * @return 统一上传返回响应体
     */
    UploadObjectResult putObject(MultipartFile object,String bucketName);

    /**
     * 上传对象到默认桶
     * @param objectInputStream 对象输入流
     * @param originalFileName 原始对象名称
     * @param size 大小
     * @param contextType 对象类型
     * @return 统一上传返回响应体
     */
    UploadObjectResult putObject(InputStream objectInputStream,String originalFileName,Long size,String contextType);

    /**
     * 上传对象到默认桶
     * @param objectInputStream 对象输入流
     * @param originalFileName 原始对象名称
     * @param size 大小
     * @param contextType 对象类型
     * @return 统一上传返回响应体
     */
    UploadObjectResult putObject(InputStream objectInputStream, String bucketName,String originalFileName,Long size,String contextType);

    /**
     * 上传对象到默认桶
     * @param object 对象文件
     * @return 统一上传返回响应体
     */
    UploadObjectResult putObject(File object);

    /**
     * 上传对象到指定桶
     * @param object 对象文件
     * @param bucketName 桶名
     * @return 统一上传返回响应体
     */
    UploadObjectResult putObject(File object, String bucketName);

    /**
     * 上传多个对象到指定桶
     * @param objects 对象文件列表
     * @param bucketName 桶名
     * @return 统一上传返回响应体列表
     */
    List<UploadObjectResult> putObjects(List<MultipartFile> objects,String bucketName);

    /**
     * 上传多个对象到默认桶
     * @param objects 对象文件列表
     * @return 统一上传返回响应体列表
     */
    List<UploadObjectResult> putObjects(List<MultipartFile> objects);

    /**
     * 上传多个对象到指定桶
     * @param objects 对象文件列表
     * @param bucketName 桶名
     * @return 统一上传返回响应体列表
     */
    List<UploadObjectResult> putObjectsOfFile(List<File> objects,String bucketName);

    /**
     * 上传多个对象到默认桶
     * @param objects 对象文件列表
     * @return 统一上传返回响应体列表
     */
    List<UploadObjectResult> putObjectsOfFile(List<File> objects);

    /**
     * 初始化大文件上传
     * @param bucketName 桶名
     * @param originalFileName 文件名
     * @return 上传标识ID
     */
    InitBigFileResult initBigFileUpload(String bucketName, String originalFileName);

    /**
     * 上传分片文件
     * @param param
     * @return
     */
    PartETag uploadPart(BigFileUploadPartParam param);
    
    /**
     * 取消分片上传
     * @param objectKey
     * @param uploadId
     */
    void abortBigFileUpload(String objectKey, String uploadId);

    /**
     * 取消分片上传
     * @param bucketName
     * @param objectKey
     * @param uploadId
     */
    void abortBigFileUpload(String bucketName, String objectKey, String uploadId);

    /**
     * 完成分片上传
     * @param param
     * @return
     */
    boolean completeBigFileUpload(BigFileUploadCompleteParam param);

    //========= 【下载】 =========

    /**
     * 下载指定桶下的对象
     * @param objectName 完整对象名
     * @param bucketName 桶名
     * @return
     */
    ResponseEntity<byte[]> getObject(String objectName, String bucketName);

    /**
     * 下载默认桶下的对象
     * @param objectName 完整对象名
     * @return
     */
    ResponseEntity<byte[]> getObject(String objectName);

    /**
     * 获取指定桶下的对象信息
     * @param objectName 完整对象名
     * @param bucketName 桶名
     * @return
     */
    S3Object getObjectInfo(String objectName,String bucketName);

    /**
     * 获取默认桶下的对象信息
     * @param objectName 完整对象名
     * @return
     */
    S3Object getObjectInfo(String objectName);

    //========= 【删除】 =========

    /**
     * 删除指定桶下的对象
     * @param objectName 完整对象名
     * @param bucketName 桶名
     */
    void deleteObject(String objectName,String bucketName);

    /**
     * 删除默认桶下的对象
     * @param objectName 完整对象名
     */
    void deleteObject(String objectName);

    /**
     * 删除列表中指定桶下的对象
     * @param objectNames 完整对象名列表
     * @param bucketName 桶名
     */
    void deleteObjects(List<String> objectNames,String bucketName);

    /**
     * 删除列表中默认桶下的对象
     * @param objectNames 完整对象名列表
     */
    void deleteObjects(List<String> objectNames);

    AmazonS3 getAmazonS3();
}
